#include "constantes.h"
#include "container.h"


void fitness(Solucion &);

void fitness1(Solucion &sol)
{
	/*int k,
	i_ocupados;

	//Dar tamaño a ocupados
	ocupados=new vector<Container>(sol.list_A.size(),Container(WIDTH,HEIGHT,DEPTH,0,sol.list_A.size()));


	//vector<double> fit_container; //fitness del contenedor
	vector<double> sum_w; //suma de los pesos de cada bloque

	sum_w.push_back(0.0);
	i_ocupados=0;

	(*ocupados)[0].z_max= 0;
	bool cajas_fuera = false;

	//Copia de la lista de cajas inicial
	vector<Box> aux(sol.list_A.size());
	vector<Box>::iterator it;
	for(int i=0; i<sol.list_A.size();i++)
	{
	aux[i] = sol.list_A[i];
	}

	//Recorremos los contenedores
	for(k=0; k <= i_ocupados; k++)
	{
	//Recorrer la lista de primer nivel
	for(it= aux.begin(); it!= aux.end();)
	{
	//La caja empieza adelante y a la derecha en el contenedor
	(*ocupados)[k].ox=WIDTH-(*it).getWidth();
	(*ocupados)[k].oz=(int)(*ocupados)[k].z_max;

	//La vamos metiendo hasta que choque con otra caja de las colocadas
	while(noChocaZ((*ocupados)[k].ox,(*ocupados)[k].oz,&(*it),(*ocupados)[k].colocadas,(*ocupados)[k].ultima_caja+1)
	&& (*ocupados)[k].oz>0)
	(*ocupados)[k].oz--;

	//La movemos hacia la izq. hasta chocar con otra de las colocadas
	while(noChocaX((*ocupados)[k].ox,(*ocupados)[k].oz,&(*it),(*ocupados)[k].colocadas,(*ocupados)[k].ultima_caja+1)
	&& (*ocupados)[k].ox>0)
	(*ocupados)[k].ox--;

	//Lo intentamos mover de nuevo hacia abajo
	while(noChocaZ((*ocupados)[k].ox,(*ocupados)[k].oz,&(*it),(*ocupados)[k].colocadas,(*ocupados)[k].ultima_caja+1)
	&& (*ocupados)[k].oz>0)
	(*ocupados)[k].oz--;

	//Guardamos las posiciones definitivas de la caja
	(*it).setX((*ocupados)[k].ox);
	(*it).setZ((*ocupados)[k].oz);
	(*it).setY(0);

	//Comprobar que la caja queda dentro del contenedor
	if((*ocupados)[k].oz+(*it).getDepth()>DEPTH
	|| (*ocupados)[k].ox+(*it).getWidth()>WIDTH
	|| sum_w[k]+(*it).getWeight() > WEIGHT)
	{
	cajas_fuera=true;
	it++; //Hacerlo aquí para que no de problemas el 'erase' del 'else'
	}
	else
	{
	//La caja entra en el contenedor: actualizo los datos del contenedor y borro la caja de la lista de cajas
	(*ocupados)[k].insertBox((*it));

	//Si al colocar una caja supero el largo que tenia hasta ahora, actualizo z_max del contenedor
	if((*ocupados)[k].z_max < (*it).getZ()+(*it).getDepth())
	(*ocupados)[k].z_max = (*it).getZ()+(*it).getDepth();

	//Una vez colocada la caja, incrementamos los pesos de cada bloque
	//asignaPesoBloque(ocupados, k, (*it));
	//actualizo el peso del contenedor
	sum_w[k]+=(*it).getWeight();

	//elimino de la lista principal la caja que ya meti
	it=aux.erase(it);
	}
	}

	if(cajas_fuera)
	{ //Hay cajas q se salen del contenedor, creo uno nuevo
	i_ocupados++;
	sum_w.push_back(0.0);
	cajas_fuera=false;
	}
	}

	sol.list_A.clear();

	//OJO, NUMBLOQUES==2
	double diff = 0.0;
	double diff_percent=0.0;
	double fitness_k = 0.0;

	double fitness_container=0.0;
	double sum_z=0.0;
	double sum_area = 0.0;


	//Para cada contenedor
	for(int i=0; i<=i_ocupados; i++)
	{ fitness_k = 0.0;
	//Calculo la diferencia de peso entre los bloques
	diff = ABSOLUTE((*ocupados)[i].bloques_z[0].weight - (*ocupados)[i].bloques_z[1].weight);

	//Calculo el porcentaje de peso que representa la diferencia sobre 1, en lugar de 100
	//if(diff>1)
	diff_percent = diff/sum_w[i];
	//else
	// diff_percent = 0;

	//Si el porcentaje de la diferencia esta entre el 0 y el 0.15 aumento fitness en la inversa de la diferencia
	if(diff_percent <= W_WEIGHT)
	fitness_k+=1/(diff_percent+0.0000001);
	//Si no, lo disminuyo en la inversa de la diferencia
	else
	fitness_k-=1/(1+0.0000001-diff_percent);


	//Sumo o resto el fitness de cada contenedor en funcion de si esta balanceado o no
	fitness_container += fitness_k;
	if(fitness_container < 0)
	fitness_container=0.0;


	//sum_area += (WIDTH*DEPTH - ((double)(*ocupados)[i].z_max* WIDTH - (double)(*ocupados)[i].area))*AREA_WEIGHT;
	sum_z+= (double)((*ocupados)[i].area)/(double)((*ocupados)[i].z_max)/(i_ocupados+1);


	//Guardo la solucion
	for(int j=0; j<(*ocupados)[i].ultima_caja+1; j++){
	sol.list_A.push_back((*ocupados)[i].colocadas[j]);
	}
	}

	//sol.fitness_value = (fitness_container + sum_area*AREA_WEIGHT + 1/(sum_z+0.0001));
	sol.fitness_value = (fitness_container + sum_z)/(i_ocupados+1);
	//cerr<<sum_area<<"\t + \t"<<sum_z<<endl;
	if(sol.fitness_value<0)
	sol.fitness_value = 0;


	delete [] ocupados;*/
}

void fitness2(Solucion &sol)
{
	/*int k,
		i_ocupados;

	//Dar tamaño a ocupados
	ocupados=new vector<Container>(sol.list_A.size(),Container(WIDTH,HEIGHT,DEPTH,0,sol.list_A.size()));

	//vector<double> fit_container;	//fitness del contenedor
	vector<double> sum_w;			//suma de los pesos de cada bloque

	i_ocupados=0;
	sum_w.push_back(0.0);


	bool cajas_fuera = false;
		
	//Copia de la lista de cajas inicial
	vector<Box> aux(sol.list_A.size());
	vector<Box>::iterator it;
	for(int i=0; i<sol.list_A.size();i++)
	{
		aux[i] = sol.list_A[i];
	}
	
	//Recorremos los contenedores
	for(k=0; k <= i_ocupados; k++)
	{

		//Recorrer la lista de primer nivel
		for(it= aux.begin(); it!= aux.end();)
		{
			//La caja empieza adelante y a la derecha en el contenedor
			(*ocupados)[k].ox=WIDTH-(*it).getWidth();
			(*ocupados)[k].oz=(int)(*ocupados)[k].z_max;

			//La vamos metiendo hasta que choque con otra caja de las colocadas
			while(noChocaZ((*ocupados)[k].ox,(*ocupados)[k].oz,&(*it),(*ocupados)[k].colocadas, (*ocupados)[k].ultima_caja+1)
				&& (*ocupados)[k].oz>0)
				(*ocupados)[k].oz--;

			//La movemos hacia la izq. hasta chocar con otra de las colocadas
			while(noChocaX((*ocupados)[k].ox,(*ocupados)[k].oz,&(*it),(*ocupados)[k].colocadas, (*ocupados)[k].ultima_caja+1)
				&& (*ocupados)[k].ox>0)
				(*ocupados)[k].ox--;

			//Lo intentamos mover de nuevo hacia abajo
			while(noChocaZ((*ocupados)[k].ox,(*ocupados)[k].oz,&(*it),(*ocupados)[k].colocadas, (*ocupados)[k].ultima_caja+1)
				&& (*ocupados)[k].oz>0)
				(*ocupados)[k].oz--;

			//Guardamos las posiciones definitivas de la caja
			(*it).setX((*ocupados)[k].ox); 	
			(*it).setZ((*ocupados)[k].oz);
			(*it).setY(0);

			//Comprobar que la caja queda dentro del contenedor
			// y que no se supera el peso máximo
			if((*ocupados)[k].oz+(*it).getDepth() > DEPTH
				|| (*ocupados)[k].ox+(*it).getWidth() > WIDTH
				|| sum_w[k]+(*it).getWeight() > WEIGHT)
			{	
				cajas_fuera=true;
				it++;	//Hacerlo aquí para que no de problemas el 'erase' del 'else'
			}
			else
			{
				//La caja entra en el contenedor: actualizo los datos del contenedor y borro la caja de la lista de cajas
				(*ocupados)[k].insertBox((*it));

				//Si al colocar una caja supero el largo que tenia hasta ahora, actualizo z_max del contenedor
				if((*ocupados)[k].z_max < (*it).getZ()+(*it).getDepth())
					(*ocupados)[k].z_max = (*it).getZ()+(*it).getDepth();

				//Una vez colocada la caja, incrementamos los pesos de cada bloque
				//asignaPesoBloque(ocupados, k, (*it));
				//actualizo el peso del contenedor
				sum_w[k]+=(*it).getWeight();

				//elimino de la lista principal la caja que ya meti
				it=aux.erase(it);
			}
		}

		if(cajas_fuera)
		{	//Hay cajas q se salen del contenedor, creo uno nuevo	
			i_ocupados++;
			sum_w.push_back(0.0);
			cajas_fuera=false;
		}
	
	}

	sol.list_A.clear();
	
	//OJO, NUMBLOQUES==2
	double diff = 0.0;
	double diff_percent=0.0;
	double fitness_k = 0.0;
	
	double fitness_container=0.0;
	double sum_z=0.0;
	double sum_area = 0.0;
	double sum_x = 0.0;
	
	//Para cada contenedor
	int ocupados_size=i_ocupados+1;
	for(int i=0; i<ocupados_size; i++)
	{	
		//Calculo la diferencia de peso entre los bloques
		diff = ABSOLUTE((*ocupados)[i].bloques_z[0].weight - (*ocupados)[i].bloques_z[1].weight);
		//Calculo el porcentaje de peso que representa la diferencia sobre 1, en lugar de 100
		diff_percent = diff/sum_w[i];
		//diff_percent=0 es ajuste perfecto

		if(diff_percent>W_WEIGHT)
			fitness_k=(-1)*diff_percent;	
		else
			fitness_k=1-diff_percent;
		
		//Sumo  o resto el fitness de cada contenedor en funcion de si esta balanceado o no
		fitness_container += fitness_k/ocupados_size;

		//Acumular los anchos
		sum_x += (((*ocupados)[i].area/((*ocupados)[i].z_max)*WIDTH))/ocupados_size;

		//Guardo la solucion
		for(int j=0; j<=(*ocupados)[i].ultima_caja; j++){
			sol.list_A.push_back((*ocupados)[i].colocadas[j]);
		}
		
	}
		
	sol.fitness_value = (fitness_container + sum_x)/2;
	if(sol.fitness_value<0)
		sol.fitness_value = 0;

	delete ocupados;*/
}

void fitness3(Solucion &sol)
{
	/*int k,
	i_ocupados,
	size_colocadas;

	//Dar tamaño a ocupados
	ocupados=new vector<Container>(sol.list_A.size(),Container(WIDTH,HEIGHT,DEPTH,0,sol.list_A.size()));

	//vector<double> fit_container; //fitness del contenedor
	vector<double> sum_w; //suma de los pesos de cada bloque

	i_ocupados=0; //Al inicio, hay un contenedor


	bool cajas_fuera;

	//Copia de la lista de cajas inicial
	vector<Box> aux(sol.list_A.size());
	vector<Box>::iterator it;
	for(int i=0; i<sol.list_A.size();i++)
	{
	aux[i] = sol.list_A[i];
	}

	//Recorremos los contenedores
	bool colocar_en_la_base;

	for(k=0; k <=i_ocupados; k++)
	{
	//Recorrer la lista de primer nivel
	cajas_fuera = false;
	for(it= aux.begin(); it!= aux.end() && !cajas_fuera;)
	{
	colocar_en_la_base=true;
	//Intentamos colocar la caja sobre la anterior si
	// # existe la caja anterior
	// && esa caja está en el nivel 1
	// && no se supera el peso admitido por el contenedor
	// && cabe sobre ella
	// && no pesa más de 750kg
	// #si no, hacemos la colocación normal.
	size_colocadas=(*ocupados)[k].ultima_caja+1;
	if( size_colocadas > 0
	&& (*ocupados)[k].colocadas[size_colocadas-1].getY()==0
	&& sum_w[k]+(*it).getWeight() <= WEIGHT
	&& (*ocupados)[k].colocadas[size_colocadas-1].getWidth() >= (*it).getWidth()
	&& (*ocupados)[k].colocadas[size_colocadas-1].getDepth() >= (*it).getDepth()
	&& (*it).getWeight() <= W_LIMIT)
	{
	//Si son de igual categoría, la caja superior no debe pesar más que la inferior
	//if((*ocupados)[k].colocadas[size_colocadas-1].getType() != (*it).getType()
	// || (*ocupados)[k].colocadas[size_colocadas-1].getSuppWeight() >= (*it).getWeight())
	if((*ocupados)[k].colocadas[size_colocadas-1].puedeSoportarA((*it),W_LIMIT))
	{
	//Se le asigna la caja base
	(*it).setBase(&((*ocupados)[k].colocadas[size_colocadas-1]));


	//Llegados aquí, se le asignan las coordenadas a la nueva caja
	(*it).setX((*it).getBase()->getX());
	(*it).setZ((*it).getBase()->getZ());
	(*it).setY((*it).getBase()->getY() + (*it).getBase()->getHeight());

	//El apilamiento no puede superar la altura máximo del contenedor
	if((*it).getY()+(*it).getHeight() <= HEIGHT)
	{
	//Se actualiza el peso soportado por la caja inferior
	(*it).getBase()->setSuppWeight((*it).getBase()->getSuppWeight() + (*it).getWeight());

	//La insertamos dentro del contenedor
	(*ocupados)[k].insertBox(*it);

	//Una vez colocada la caja, incrementamos los pesos de cada bloque
	//asignaPesoBloque(ocupados, k, (*it));
	//actualizo el peso del contenedor
	sum_w[k]+=(*it).getWeight();

	//elimino de la lista principal la caja que ya meti
	it=aux.erase(it);

	colocar_en_la_base=false;
	}
	}
	}

	if(colocar_en_la_base)
	{
	//La caja empieza adelante y a la derecha en el contenedor
	(*ocupados)[k].ox=WIDTH-(*it).getWidth();
	(*ocupados)[k].oz=(int)(*ocupados)[k].z_max;

	//La vamos metiendo hasta que choque con otra caja de las colocadas
	while(noChocaZ((*ocupados)[k].ox,(*ocupados)[k].oz,&(*it),(*ocupados)[k].colocadas, (*ocupados)[k].ultima_caja+1)
	&& (*ocupados)[k].oz>0)
	(*ocupados)[k].oz--;

	//La movemos hacia la izq. hasta chocar con otra de las colocadas
	while(noChocaX((*ocupados)[k].ox,(*ocupados)[k].oz,&(*it),(*ocupados)[k].colocadas, (*ocupados)[k].ultima_caja+1)
	&& (*ocupados)[k].ox>0)
	(*ocupados)[k].ox--;

	//Lo intentamos mover de nuevo hacia abajo
	while(noChocaZ((*ocupados)[k].ox,(*ocupados)[k].oz,&(*it),(*ocupados)[k].colocadas, (*ocupados)[k].ultima_caja+1)
	&& (*ocupados)[k].oz>0)
	(*ocupados)[k].oz--;

	//Guardamos las posiciones definitivas de la caja
	(*it).setX((*ocupados)[k].ox);
	(*it).setZ((*ocupados)[k].oz);
	(*it).setY(0);

	//Comprobar que la caja queda dentro del contenedor
	if((*ocupados)[k].oz+(*it).getDepth()>DEPTH
	|| (*ocupados)[k].ox+(*it).getWidth()>WIDTH
	|| sum_w[k]+(*it).getWeight() > WEIGHT)
	{
	cajas_fuera=true;
	it++; //Hacerlo aquí para que no de problemas el 'erase' del 'else'
	}
	else
	{
	//La caja entra en el contenedor: actualizo los datos del contenedor y borro la caja de la lista de cajas
	//La insertamos dentro del contenedor
	(*ocupados)[k].insertBox((*it));

	//Si al colocar una caja supero el largo que tenia hasta ahora, actualizo z_max del contenedor
	if((*ocupados)[k].z_max < (*it).getZ()+(*it).getDepth())
	(*ocupados)[k].z_max = (*it).getZ()+(*it).getDepth();

	//Una vez colocada la caja, incrementamos los pesos de cada bloque
	//asignaPesoBloque(ocupados, k, (*it));
	//actualizo el peso del contenedor
	sum_w[k]+=(*it).getWeight();

	//elimino de la lista principal la caja que ya meti
	it=aux.erase(it);
	}
	}
	}

	if(cajas_fuera)
	{ //Hay cajas q se salen del contenedor, creo uno nuevo
	sum_w.push_back(0.0);
	i_ocupados++;
	cajas_fuera=false;
	}

	}

	sol.list_A.clear();

	//OJO, NUMBLOQUES==2
	double diff = 0.0;
	double diff_percent=0.0;
	double fitness_k = 0.0;

	double fitness_container=0.0;
	double sum_z=0.0;
	double sum_area = 0.0;
	double sum_y = 0.0;
	double sum_y_caja;

	//Para cada contenedor
	int ocupados_size=i_ocupados+1;
	for(int i=0; i<ocupados_size; i++)
	{
	//Calculo la diferencia de peso entre los bloques
	diff = ABSOLUTE((*ocupados)[i].bloques_z[0].weight - (*ocupados)[i].bloques_z[1].weight);
	//Calculo el porcentaje de peso que representa la diferencia sobre 1, en lugar de 100
	diff_percent = diff/sum_w[i];
	//diff_percent=0 es ajuste perfecto

	if(diff_percent>W_WEIGHT)
	fitness_k=(-1)*diff_percent;
	else
	fitness_k=1-diff_percent;

	//Sumo o resto el fitness de cada contenedor en funcion de si esta balanceado o no
	fitness_container += fitness_k/ocupados_size;

	//Acumular áreas
	sum_area += ((*ocupados)[i].area/(double)(WIDTH*DEPTH))/(double)ocupados_size;

	//Guardo la solucion
	sum_y_caja=0;
	for(int j=0; j<(*ocupados)[i].ultima_caja+1; j++){
	sum_y_caja+=(*ocupados)[i].colocadas[j].getY()+(*ocupados)[i].colocadas[j].getHeight();
	sol.list_A.push_back((*ocupados)[i].colocadas[j]);
	}

	//Acumular las alturas
	sum_y_caja /= (double)((*ocupados)[i].ultima_caja+1); //Altura media de las cajas en el contenedor
	sum_y += sum_y_caja/(double)HEIGHT/(double)ocupados_size;
	}

	sol.fitness_value = (fitness_container + sum_y + sum_area )/3;
	if(sol.fitness_value<0)
	sol.fitness_value = 0;*/
}

void fitness4(Solucion &sol)
{
	/*int k,
	i_ocupados,
	size_colocadas,
	index,
	ox_aux,
	x_base,
	oz_aux,
	z_base;

	//Dar tamaño a ocupados
	ocupados=new vector<Container>(sol.list_A.size(),Container(WIDTH,HEIGHT,DEPTH,0,sol.list_A.size()));

	//vector<double> fit_container; //fitness del contenedor
	vector<double> sum_w; //suma de los pesos de cada bloque

	vector<Box> colocadas_aux;

	i_ocupados=0; //Al inicio, hay un contenedor
	sum_w.push_back(0.0);

	bool cajas_fuera;

	//Copia de la lista de cajas inicial
	vector<Box> aux(sol.list_A.size());
	vector<Box>::iterator it;
	for(int i=0; i<sol.list_A.size();i++)
	{
	aux[i] = sol.list_A[i];
	}

	//Recorremos los contenedores
	bool colocar_en_la_base;
	for(k=0; k <= i_ocupados; k++)
	{
	//Recorrer la lista de primer nivel
	cajas_fuera = false;
	for(it= aux.begin(); it!= aux.end();)
	{
	colocar_en_la_base=true;
	//Comprobar el límite de peso del contenedor
	if(sum_w[k]+(*it).getWeight() > WEIGHT)
	{
	cajas_fuera = true;
	break;
	}

	//Intentamos colocar la caja sobre la anterior si
	// # existe la caja anterior
	// && esa caja está en el nivel 1
	// && no se supera el peso admitido por el contenedor
	// && juntas no superan la altura máxima del contenedor
	// #si no, hacemos la colocación normal.
	size_colocadas=(*ocupados)[k].ultima_caja+1;
	if( size_colocadas > 0
	&& (*ocupados)[k].colocadas[size_colocadas-1].getY()==0
	&& (*ocupados)[k].colocadas[size_colocadas-1].getY() + (*ocupados)[k].colocadas[size_colocadas-1].getHeight()
	+(*it).getHeight() <= HEIGHT)
	{
	// cabe sobre ella
	if((*ocupados)[k].colocadas[size_colocadas-1].puedeSoportarA((*it),W_LIMIT))
	{
	//Se le asigna la caja base
	(*it).setBase(&((*ocupados)[k].colocadas[size_colocadas-1]));


	//Llegados aquí, se le asignan las coordenadas a la nueva caja
	(*it).setX((*it).getBase()->getX());
	(*it).setZ((*it).getBase()->getZ());
	(*it).setY((*it).getBase()->getY() + (*it).getBase()->getHeight());

	//Se actualiza el peso soportado por la caja inferior
	(*it).getBase()->setSuppWeight((*it).getBase()->getSuppWeight() + (*it).getWeight());

	//La insertamos dentro del contenedor
	(*ocupados)[k].insertBox(*it);

	//Una vez colocada la caja, incrementamos los pesos de cada bloque
	//asignaPesoBloque(ocupados, k, (*it));
	//actualizo el peso del contenedor
	sum_w[k]+=(*it).getWeight();

	//elimino de la lista principal la caja que ya meti
	it=aux.erase(it);

	colocar_en_la_base=false;
	}
	}
	// #La caja anterior esta en el nivel 2. Intentamos colocar la nueva caja
	// sobre la que soporta a esa caja anterior
	else if(size_colocadas >= 2
	&& (*ocupados)[k].colocadas[size_colocadas-1].getY()!=0
	&& (*ocupados)[k].colocadas[size_colocadas-1].getBase()->getBase()==NULL) //No está en el 3er nivel
	{
	//Buscar la caja de la base
	for(index=size_colocadas-2;
	index>=0 && (*ocupados)[k].colocadas[index].getY()>0;
	index--);

	if(index>=0)
	{
	//Comprobar que:
	// #la caja base soporta la nueva caja que queremos colocar
	// #no se supera el límite de altura del contenedor
	if((*ocupados)[k].colocadas[index].puedeSoportarA((*it),W_LIMIT)
	&& (*ocupados)[k].colocadas[index].getY()+(*it).getHeight()<=HEIGHT)
	{
	//Rellenar un vector de ocupados auxiliar con las cajas que ya están
	// sobre la caja base
	colocadas_aux.resize(size_colocadas-index-1);
	for(int i=0; i<size_colocadas-index-1; i++)
	{
	colocadas_aux[i]=(*ocupados)[k].colocadas[index+i+1];
	}

	//Coordenadas iniciales para desplazar la caja
	z_base=(*ocupados)[k].colocadas[index].getZ();
	oz_aux= z_base + (*ocupados)[k].colocadas[index].getDepth();
	x_base=(*ocupados)[k].colocadas[index].getX();
	ox_aux= x_base + (*ocupados)[k].colocadas[index].getWidth()-(*it).getWidth();

	//Desplazar la nueva caja sobre el eje Z
	while(noChocaZ(ox_aux,oz_aux,&(*it),colocadas_aux,size_colocadas-index-1)
	&& oz_aux>z_base)
	oz_aux--;

	//Desplazar la nueva caja sobre el eje X
	while(noChocaX(ox_aux,oz_aux,&(*it),colocadas_aux,size_colocadas-index-1)
	&& ox_aux>x_base)
	ox_aux--;

	//Desplazar la nueva caja sobre el eje Z
	while(noChocaZ(ox_aux,oz_aux,&(*it),colocadas_aux,size_colocadas-index-1)
	&& oz_aux>z_base)
	oz_aux--;

	//Comprobar que las coordenadas obtenidas están dentro de las dimensiones
	// de la caja base
	if(oz_aux+(*it).getDepth()<=(*ocupados)[k].colocadas[index].getZ()+(*ocupados)[k].colocadas[index].getDepth()
	&& ox_aux+(*it).getWidth()<=(*ocupados)[k].colocadas[index].getX()+(*ocupados)[k].colocadas[index].getWidth())
	{
	//Se le asigna la caja base
	(*it).setBase(&((*ocupados)[k].colocadas[index]));

	//Llegados aquí, se le asignan las coordenadas a la nueva caja
	(*it).setX(ox_aux);
	(*it).setZ(oz_aux);
	(*it).setY((*ocupados)[k].colocadas[size_colocadas-1].getY());

	//Se actualiza el peso soportado por la caja inferior
	(*it).getBase()->setSuppWeight((*it).getBase()->getSuppWeight() + (*it).getWeight());

	//La insertamos dentro del contenedor
	(*ocupados)[k].insertBox((*it));

	//Una vez colocada la caja, incrementamos los pesos de cada bloque
	//asignaPesoBloque(ocupados, k, (*it));
	//actualizo el peso del contenedor
	sum_w[k]+=(*it).getWeight();

	//elimino de la lista principal la caja que ya meti
	it=aux.erase(it);

	colocar_en_la_base=false;
	}
	} //if_soporta
	} //else_if_colocadas
	}

	if(cajas_fuera)
	break;

	if(colocar_en_la_base)
	{
	//La caja empieza adelante y a la derecha en el contenedor
	(*ocupados)[k].ox=WIDTH-(*it).getWidth();
	(*ocupados)[k].oz=(int)(*ocupados)[k].z_max;

	//La vamos metiendo hasta que choque con otra caja de las colocadas
	while(noChocaZ((*ocupados)[k].ox,(*ocupados)[k].oz,&(*it),(*ocupados)[k].colocadas, (*ocupados)[k].ultima_caja+1)
	&& (*ocupados)[k].oz>0)
	(*ocupados)[k].oz--;

	//La movemos hacia la izq. hasta chocar con otra de las colocadas
	while(noChocaX((*ocupados)[k].ox,(*ocupados)[k].oz,&(*it),(*ocupados)[k].colocadas, (*ocupados)[k].ultima_caja+1)
	&& (*ocupados)[k].ox>0)
	(*ocupados)[k].ox--;

	//Lo intentamos mover de nuevo hacia abajo
	while(noChocaZ((*ocupados)[k].ox,(*ocupados)[k].oz,&(*it),(*ocupados)[k].colocadas, (*ocupados)[k].ultima_caja+1)
	&& (*ocupados)[k].oz>0)
	(*ocupados)[k].oz--;

	(*it).setBase(NULL);

	//Guardamos las posiciones definitivas de la caja
	(*it).setX((*ocupados)[k].ox);
	(*it).setZ((*ocupados)[k].oz);
	(*it).setY(0);

	//Comprobar que la caja queda dentro del contenedor
	if((*ocupados)[k].oz+(*it).getDepth()>DEPTH
	|| (*ocupados)[k].ox+(*it).getWidth()>WIDTH)
	{
	cajas_fuera=true;
	it++; //Hacerlo aquí para que no de problemas el 'erase' del 'else'
	}
	else
	{
	//La caja entra en el contenedor: actualizo los datos del contenedor y borro la caja de la lista de cajas
	(*ocupados)[k].insertBox((*it));

	//Si al colocar una caja supero el largo que tenia hasta ahora, actualizo z_max del contenedor
	if((*ocupados)[k].z_max < (*it).getZ()+(*it).getDepth())
	(*ocupados)[k].z_max = (*it).getZ()+(*it).getDepth();

	//Una vez colocada la caja, incrementamos los pesos de cada bloque
	//asignaPesoBloque(ocupados, k, (*it));
	//actualizo el peso del contenedor
	sum_w[k]+=(*it).getWeight();

	//elimino de la lista principal la caja que ya meti
	it=aux.erase(it);
	}
	}
	}

	if(cajas_fuera)
	{ //Hay cajas q se salen del contenedor, creo uno nuevo
	i_ocupados++;
	sum_w.push_back(0.0);
	cajas_fuera=false;
	}

	}

	sol.list_A.clear();

	//OJO, NUMBLOQUES==2
	double diff = 0.0;
	double diff_percent=0.0;
	double fitness_k = 0.0;

	double fitness_container=0.0;
	double sum_area = 0.0;
	double sum_vol = 0.0;

	//Para cada contenedor
	int ocupados_size=i_ocupados+1;
	for(int i=0; i<ocupados_size; i++)
	{
	//Calculo la diferencia de peso entre los bloques
	diff = ABSOLUTE((*ocupados)[i].bloques_z[0].weight - (*ocupados)[i].bloques_z[1].weight);
	//Calculo el porcentaje de peso que representa la diferencia sobre 1, en lugar de 100
	diff_percent = diff/sum_w[i];
	//diff_percent=0 es ajuste perfecto

	if(diff_percent>W_WEIGHT)
	fitness_k=0;
	else
	fitness_k=1-diff_percent;

	//Sumo o resto el fitness de cada contenedor en funcion de si esta balanceado o no
	fitness_container += fitness_k/ocupados_size;

	//Acumular volumenes
	sum_vol += (*ocupados)[i].getOcupacion()/(double)ocupados_size;


	//Acumular áreas (viene en tanto por 100)
	sum_area += (*ocupados)[i].getArea()/(double)ocupados_size;

	//Guardo la solucion
	for(int j=0; j<(*ocupados)[i].ultima_caja+1; j++){
	sol.list_A.push_back((*ocupados)[i].colocadas[j]);
	}
	}

	sol.fitness_value = (fitness_container + 2*sum_area/100.0 + 7*sum_vol/100.0)/10.0;
	if(sol.fitness_value<0)
	sol.fitness_value = 0;

	delete ocupados;*/
}

void fitness4_var(Solucion &sol)
{
	/*int k,
	i_ocupados,
	size_colocadas,
	index,
	ox_aux,
	x_base,
	oz_aux,
	z_base;

	//Dar tamaño a ocupados
	ocupados=new vector<Container>(sol.list_A.size(),Container(WIDTH,HEIGHT,DEPTH,0,sol.list_A.size()));

	//vector<double> fit_container; //fitness del contenedor
	vector<double> sum_w; //suma de los pesos de cada bloque

	vector<Box> colocadas_aux;

	i_ocupados=0; //Al inicio, hay un contenedor
	sum_w.push_back(0.0);

	bool cajas_fuera;

	//Copia de la lista de cajas inicial
	vector<Box> aux(sol.list_A.size());
	vector<Box>::iterator it;
	for(int i=0; i<sol.list_A.size();i++)
	{
	aux[i] = sol.list_A[i];
	}

	//Recorremos los contenedores
	bool colocar_en_la_base;
	for(k=0; k <= i_ocupados; k++)
	{
		//Recorrer la lista de primer nivel
		cajas_fuera = false;
		for(it= aux.begin(); it!= aux.end();)
		{
			colocar_en_la_base=true;
			//Intentamos colocar la caja sobre la anterior si
			// # existe la caja anterior
			// && esa caja está en el nivel 1
			// && no se supera el peso admitido por el contenedor
			// && cabe sobre ella
			// && juntas no superan la altura máxima del contenedor
			// #si no, hacemos la colocación normal.
			size_colocadas=(*ocupados)[k].ultima_caja+1;
			for(int i=0; i<size_colocadas && it!= aux.end();i++)
			{
				//Intento meterla encima de cualquier caja ya colocada, que no tenga ninguna encima
				if( size_colocadas >= 0
					&& ((*ocupados)[k].colocadas[i].getEsBase()==false)
					&& (*ocupados)[k].colocadas[i].getY()==0
					&& sum_w[k]+(*it).getWeight() <= WEIGHT
					&& (*ocupados)[k].colocadas[i].getWidth() >= (*it).getWidth()
					&& (*ocupados)[k].colocadas[i].getDepth() >= (*it).getDepth()
					&& (*ocupados)[k].colocadas[i].getY() + (*ocupados)[k].colocadas[i].getHeight()
					+(*it).getHeight() <= HEIGHT)
				{

					if((*ocupados)[k].colocadas[i].puedeSoportarA((*it),W_LIMIT))
					{
						//Se le asigna la caja base
						(*it).setBase(&((*ocupados)[k].colocadas[i]));
						(*ocupados)[k].colocadas[i].setEsBase(true);

						//Llegados aquí, se le asignan las coordenadas a la nueva caja
						(*it).setX((*it).getBase()->getX());
						(*it).setZ((*it).getBase()->getZ());
						(*it).setY((*it).getBase()->getY() + (*it).getBase()->getHeight());

						//Se actualiza el peso soportado por la caja inferior
						(*it).getBase()->setSuppWeight((*it).getBase()->getSuppWeight() + (*it).getWeight());

						//La insertamos dentro del contenedor
						(*ocupados)[k].insertBox(*it);

						//Una vez colocada la caja, incrementamos los pesos de cada bloque
						//asignaPesoBloque(ocupados, k, (*it));
						//actualizo el peso del contenedor
						sum_w[k]+=(*it).getWeight();

						//elimino de la lista principal la caja que ya meti
						it=aux.erase(it);

						colocar_en_la_base=false;
						break;
					}
				}

				// #La caja anterior esta en el nivel 2. Intentamos colocar la nueva caja
				// sobre la que soporta a esa caja anterior
				else
				if(size_colocadas >= 2
				&& (*ocupados)[k].colocadas[i].getY()!=0
				&& it!=aux.end())
				{
					//Buscar la caja de la base
					for(index=size_colocadas-1;
						index>=0
						&& (*ocupados)[k].colocadas[i].getBase() != &(*ocupados)[k].colocadas[index];
						index--)
					{
						if(index==i)
						continue;
					}

					if(index>=0)
					{
						//Comprobar que:
						// #la caja base soporta la nueva caja que queremos colocar
						// #no se supera el límite de altura del contenedor
						if(	(*ocupados)[k].colocadas[index].puedeSoportarA((*it),W_LIMIT)
							&& (*ocupados)[k].colocadas[index].getY()+ (*ocupados)[k].colocadas[index].getHeight()
							+(*it).getHeight()<=HEIGHT
							&& (*it).getDepth()<=(*ocupados)[k].colocadas[index].getDepth()
							&& (*it).getWidth()<=(*ocupados)[k].colocadas[index].getWidth())
						{

							//Recorro todas las cajas colocadas
							colocadas_aux.resize(size_colocadas-1);
							int num_encima=0;
							for(int j=0; j<size_colocadas; j++)
							{ //Si hay alguna que tenga por base la misma que la caja i, se inserta en el vector
								if((*ocupados)[k].colocadas[j].getBase() == &(*ocupados)[k].colocadas[index]){
								colocadas_aux[num_encima]=(*ocupados)[k].colocadas[j];
								num_encima++;
							}
						}

						//Coordenadas iniciales para desplazar la caja
						z_base=(*ocupados)[k].colocadas[index].getZ();
						oz_aux= z_base + (*ocupados)[k].colocadas[index].getDepth();
						x_base=(*ocupados)[k].colocadas[index].getX();
						ox_aux= x_base + (*ocupados)[k].colocadas[index].getWidth()-(*it).getWidth();

						//Desplazar la nueva caja sobre el eje Z
						while(noChocaZ(ox_aux,oz_aux,&(*it),colocadas_aux,num_encima)
						&& oz_aux>z_base)
						oz_aux--;

						//Desplazar la nueva caja sobre el eje X
						while(noChocaX(ox_aux,oz_aux,&(*it),colocadas_aux,num_encima)
						&& ox_aux>x_base)
						ox_aux--;

						//Desplazar la nueva caja sobre el eje Z
						while(noChocaZ(ox_aux,oz_aux,&(*it),colocadas_aux,num_encima)
						&& oz_aux>z_base)
						oz_aux--;

						//Comprobar que las coordenadas obtenidas están dentro de las dimensiones
						// de la caja base
						if(oz_aux+(*it).getDepth()<=(*ocupados)[k].colocadas[index].getZ()+(*ocupados)[k].colocadas[index].getDepth()
						&& ox_aux+(*it).getWidth()<=(*ocupados)[k].colocadas[index].getX()+(*ocupados)[k].colocadas[index].getWidth())
						{
							//Se le asigna la caja base
							(*it).setBase(&((*ocupados)[k].colocadas[index]));

							//indicamos que la caja index ya tiene algo encima
							(*ocupados)[k].colocadas[index].setEsBase(true);

							//Llegados aquí, se le asignan las coordenadas a la nueva caja
							(*it).setX(ox_aux);
							(*it).setZ(oz_aux);
							(*it).setY((*it).getBase()->getY() + (*it).getBase()->getHeight());

							//Se actualiza el peso soportado por la caja inferior
							(*it).getBase()->setSuppWeight((*it).getBase()->getSuppWeight() + (*it).getWeight());

							//La insertamos dentro del contenedor
							(*ocupados)[k].insertBox((*it));


							//Una vez colocada la caja, incrementamos los pesos de cada bloque
							//asignaPesoBloque(ocupados, k, (*it));
							//actualizo el peso del contenedor
							sum_w[k]+=(*it).getWeight();

							//elimino de la lista principal la caja que ya meti
							it=aux.erase(it);

							colocar_en_la_base=false;
						}//if_cabe_encima

						else //3er nivel
							if(it!=aux.end())
						{
						index=i;

						//Comprobar que:
						// #no se supera el límite de altura del contenedor, ni del ancho y longitud de la caja
						// #la caja base soporta la nueva caja que queremos colocar
						if(index>=0
							&& (*ocupados)[k].colocadas[index].puedeSoportarA((*it),W_LIMIT)
							&& (*ocupados)[k].colocadas[index].getY()+(*ocupados)[k].colocadas[index].getHeight()+(*it).getHeight()<=HEIGHT
							&& (*it).getDepth()<=(*ocupados)[k].colocadas[index].getDepth()
							&& (*it).getWidth()<=(*ocupados)[k].colocadas[index].getWidth())
						{
							//Rellenar un vector de ocupados auxiliar con las cajas que ya están
							// sobre la caja base
							//Recorro todas las cajas colocadas
							colocadas_aux.resize(size_colocadas-1);
							int num_encima=0;
							for(int j=0; j<size_colocadas; j++)
							{ //Si hay alguna que tenga por base la misma que la caja i, se inserta en el vector
								if((*ocupados)[k].colocadas[j].getBase() == &(*ocupados)[k].colocadas[index]){
								colocadas_aux[num_encima]=(*ocupados)[k].colocadas[j];
								num_encima++;
							}
						}

						//Coordenadas iniciales para desplazar la caja
						z_base=(*ocupados)[k].colocadas[index].getZ();
						oz_aux= z_base + (*ocupados)[k].colocadas[index].getDepth();
						x_base=(*ocupados)[k].colocadas[index].getX();
						ox_aux= x_base + (*ocupados)[k].colocadas[index].getWidth()-(*it).getWidth();

						//Desplazar la nueva caja sobre el eje Z
						while(noChocaZ(ox_aux,oz_aux,&(*it),colocadas_aux,num_encima)
						&& oz_aux>z_base)
						oz_aux--;

						//Desplazar la nueva caja sobre el eje X
						while(noChocaX(ox_aux,oz_aux,&(*it),colocadas_aux,num_encima)
						&& ox_aux>x_base)
						ox_aux--;

						//Desplazar la nueva caja sobre el eje Z
						while(noChocaZ(ox_aux,oz_aux,&(*it),colocadas_aux,num_encima)
						&& oz_aux>z_base)
						oz_aux--;

						//Comprobar que las coordenadas obtenidas están dentro de las dimensiones
						// de la caja base
						if(oz_aux+(*it).getDepth()<=(*ocupados)[k].colocadas[index].getZ()+(*ocupados)[k].colocadas[index].getDepth()
						&& ox_aux+(*it).getWidth()<=(*ocupados)[k].colocadas[index].getX()+(*ocupados)[k].colocadas[index].getWidth())
						{
							//Se le asigna la caja base
							(*it).setBase(&((*ocupados)[k].colocadas[index]));

							//Llegados aquí, se le asignan las coordenadas a la nueva caja
							(*it).setX(ox_aux);
							(*it).setZ(oz_aux);
							(*it).setY((*it).getBase()->getY()+(*it).getBase()->getHeight());

							//Se actualiza el peso soportado por la caja inferior
							(*it).getBase()->setSuppWeight((*it).getBase()->getSuppWeight() + (*it).getWeight());

							//La insertamos dentro del contenedor
							(*ocupados)[k].insertBox((*it));

							//Una vez colocada la caja, incrementamos los pesos de cada bloque
							//asignaPesoBloque(ocupados, k, (*it));
							//actualizo el peso del contenedor
							sum_w[k]+=(*it).getWeight();

							//elimino de la lista principal la caja que ya meti
							it=aux.erase(it);

							colocar_en_la_base=false;
						}
					}
				}//else_3er_nivel
			}//if_puede_soportar
		}//if_encontre_base
	}//else_if
	}//for_recorre_colocadas

	if(cajas_fuera)
		break;


	if(colocar_en_la_base)
	{
		//La caja empieza adelante y a la derecha en el contenedor
		(*ocupados)[k].ox=WIDTH-(*it).getWidth();
		(*ocupados)[k].oz=(int)(*ocupados)[k].z_max;

		//La vamos metiendo hasta que choque con otra caja de las colocadas
		while(noChocaZ((*ocupados)[k].ox,(*ocupados)[k].oz,&(*it),(*ocupados)[k].colocadas, (*ocupados)[k].ultima_caja+1)
		&& (*ocupados)[k].oz>0)
		(*ocupados)[k].oz--;

		//La movemos hacia la izq. hasta chocar con otra de las colocadas
		while(noChocaX((*ocupados)[k].ox,(*ocupados)[k].oz,&(*it),(*ocupados)[k].colocadas, (*ocupados)[k].ultima_caja+1)
		&& (*ocupados)[k].ox>0)
		(*ocupados)[k].ox--;

		//Lo intentamos mover de nuevo hacia abajo
		while(noChocaZ((*ocupados)[k].ox,(*ocupados)[k].oz,&(*it),(*ocupados)[k].colocadas, (*ocupados)[k].ultima_caja+1)
		&& (*ocupados)[k].oz>0)
		(*ocupados)[k].oz--;

		(*it).setBase(NULL);

		//Guardamos las posiciones definitivas de la caja
		(*it).setX((*ocupados)[k].ox);
		(*it).setZ((*ocupados)[k].oz);
		(*it).setY(0);

		//Comprobar que la caja queda dentro del contenedor
		if((*ocupados)[k].oz+(*it).getDepth()>DEPTH
		|| (*ocupados)[k].ox+(*it).getWidth()>WIDTH
		|| sum_w[k]+(*it).getWeight() > WEIGHT)
		{
			cajas_fuera=true;
			it=aux.begin(); //Hacerlo aquí para que no de problemas el 'erase' del 'else'
		}
		else
		{
			//La caja entra en el contenedor: actualizo los datos del contenedor y borro la caja de la lista de cajas
			(*ocupados)[k].insertBox((*it));
			//(*ocupados)[k].area += (*it).getDepth()*(*it).getWidth();

		//Si al colocar una caja supero el largo que tenia hasta ahora, actualizo z_max del contenedor
		if((*ocupados)[k].z_max < (*it).getZ()+(*it).getDepth())
			(*ocupados)[k].z_max = (*it).getZ()+(*it).getDepth();

		//Una vez colocada la caja, incrementamos los pesos de cada bloque
		//asignaPesoBloque(ocupados, k, (*it));
		//actualizo el peso del contenedor
		sum_w[k]+=(*it).getWeight();

		//elimino de la lista principal la caja que ya meti
		it=aux.erase(it);
	}
	}


	}
	if(cajas_fuera)
	{ //Hay cajas q se salen del contenedor, creo uno nuevo
	i_ocupados++;
	sum_w.push_back(0.0);
	cajas_fuera=false;
	}

	}

	sol.list_A.clear();

	//OJO, NUMBLOQUES==2
	double diff = 0.0;
	double diff_percent=0.0;
	double fitness_k = 0.0;

	double fitness_container=0.0;
	double sum_z=0.0;
	double sum_area = 0.0;
	double sum_x = 0.0;
	double sum_y = 0.0;
	double sum_y_caja=0.0;
	double sum_vol = 0.0;

	//Para cada contenedor
	int ocupados_size=i_ocupados+1;
	for(int i=0; i<ocupados_size; i++)
	{
	//Calculo la diferencia de peso entre los bloques
	diff = ABSOLUTE((*ocupados)[i].bloques_z[0].weight - (*ocupados)[i].bloques_z[1].weight);
	//Calculo el porcentaje de peso que representa la diferencia sobre 1, en lugar de 100
	diff_percent = diff/sum_w[i];
	//diff_percent=0 es ajuste perfecto

	if(diff_percent>W_WEIGHT)
	fitness_k = (-1)*diff_percent;
	else{
	fitness_k = 1-diff_percent;
	}

	fitness_container += fitness_k/ocupados_size;


	//Acumular los volúmenes de ocupación (en tanto por 100)
	sum_vol += ((*ocupados)[i].getOcupacion())/(double)ocupados_size;

	//Acumular áreas (viene en tanto por 100)
	sum_area += ((*ocupados)[i].getArea())/(double)ocupados_size;

	//Guardo la solucion
	sum_y_caja=0;
	for(int j=0; j<(*ocupados)[i].ultima_caja+1; j++){
	sum_y_caja+=(*ocupados)[i].colocadas[j].getY()+(*ocupados)[i].colocadas[j].getHeight();
	sol.list_A.push_back((*ocupados)[i].colocadas[j]);
	}

	//Acumular las alturas
	sum_y_caja /= (double)((*ocupados)[i].ultima_caja+1); //Altura media de las cajas en el contenedor
	sum_y += sum_y_caja/(double)HEIGHT/(double)ocupados_size;
	}





	sol.fitness_value = (fitness_container + sum_y+ 7*(sum_vol/100.0) + (sum_area/100.0))/10;
	if(sol.fitness_value<0)
	sol.fitness_value = 0;

	delete ocupados;*/
}

void fitness5(Solucion &sol)
{
	
	/*int k,
		i_ocupados,
		size_colocadas,
		index,
		ox_aux,
		x_base,
		oz_aux,
		z_base;

	//Dar tamaño a ocupados
	ocupados=new vector<Container>(sol.list_A.size(),Container(WIDTH,HEIGHT,DEPTH,0,WEIGHT,sol.list_A.size()));

	//vector<double> fit_container;	//fitness del contenedor
	vector<double> sum_w;			//suma de los pesos de cada bloque

	vector<Box> colocadas_aux;

	i_ocupados=0;	//Al inicio, hay un contenedor
	sum_w.push_back(0.0);
	
	bool cajas_fuera;
	
	//Copia de la lista de cajas inicial
	vector<Box> aux(sol.list_A.size());
	vector<Box>::iterator it;
	for(int i=0; i<sol.list_A.size();i++)
	{
		aux[i] = sol.list_A[i];
	}
	
	//Recorremos los contenedores
	bool colocar_en_la_base;
	for(k=0; k <= i_ocupados; k++)
	{
		//Recorrer la lista de primer nivel
		cajas_fuera = false;
		for(it= aux.begin(); it!= aux.end();)
		{
			colocar_en_la_base=true;
			//Comprobar el límite de peso del contenedor
			if(sum_w[k]+(*it).getWeight() > WEIGHT)
			{
				cajas_fuera = true;
				break;
			}

			//Intentamos colocar la caja sobre la anterior si
			//	# existe la caja anterior 
			//	  && esa caja está en el nivel 1
			//	  && no se supera el peso admitido por el contenedor 
			//	  && juntas no superan la altura máxima del contenedor
			//  #si no, hacemos la colocación normal.
			size_colocadas=(*ocupados)[k].ultima_caja+1;
				//Entra por aki cuando hay cajas en el segundo nivel, y asigna coordenadas iguales a cajas que no pueden ir 
				//en el mismo sitio
			if( size_colocadas > 0
				&& (*ocupados)[k].colocadas[size_colocadas-1].getY()==0)
			{
				//	  cabe sobre ella 
				if((*ocupados)[k].colocadas[size_colocadas-1].puedeSoportarA((*it),W_LIMIT,HEIGHT))
				{
					//Se le asigna la caja base
					(*it).setBase(&((*ocupados)[k].colocadas[size_colocadas-1]));

					//Llegados aquí, se le asignan las coordenadas a la nueva caja
					(*it).setX((*it).getBase()->getX()); 	
					(*it).setZ((*it).getBase()->getZ());
					(*it).setY((*it).getBase()->getY() + (*it).getBase()->getHeight());				

					//Se actualiza el peso soportado por la caja inferior
					(*it).getBase()->setSuppWeight((*it).getBase()->getSuppWeight() + (*it).getWeight());

					//La insertamos dentro del contenedor
					(*ocupados)[k].insertBox(*it); 

					//Una vez colocada la caja, incrementamos los pesos de cada bloque
					//asignaPesoBloque(ocupados, k, (*it));
					//actualizo el peso del contenedor
					sum_w[k]+=(*it).getWeight();

					//elimino de la lista principal la caja que ya meti
					it=aux.erase(it);

					colocar_en_la_base=false;
				}
			}
			else if(size_colocadas >= 2)
			{
				//	#La caja anterior esta en el nivel 2. Intentamos colocar la nueva caja
				//	 sobre la que soporta a esa caja anterior
				if((*ocupados)[k].colocadas[size_colocadas-1].getY()!=0
					&& (*ocupados)[k].colocadas[size_colocadas-1].getBase()->getBase()==NULL) //No está en el 3er nivel
				{
					//Buscar la caja de la base
					for(index=size_colocadas-2; 
						index>=0 && (*ocupados)[k].colocadas[index].getY()>0;
						index--);

					//Comprobar que:
					//	#la caja base soporta la nueva caja que queremos colocar
					//	#no se supera el límite de altura del contenedor
					if(index>=0
						&& (*ocupados)[k].colocadas[index].puedeSoportarA((*it),W_LIMIT,HEIGHT))
					{
						//Rellenar un vector de ocupados auxiliar con las cajas que ya están
						// sobre la caja base
						colocadas_aux.resize(size_colocadas-index-1);
						for(int i=0; i<size_colocadas-index-1; i++)
						{
							colocadas_aux[i]=(*ocupados)[k].colocadas[index+i+1];
						}

						//Coordenadas iniciales para desplazar la caja
						z_base=(*ocupados)[k].colocadas[index].getZ();
						oz_aux= z_base + (*ocupados)[k].colocadas[index].getDepth();
						x_base=(*ocupados)[k].colocadas[index].getX();
						ox_aux= x_base + (*ocupados)[k].colocadas[index].getWidth()-(*it).getWidth();

						//Desplazar la nueva caja sobre el eje Z
						while(noChocaZ(ox_aux,oz_aux,&(*it),colocadas_aux,size_colocadas-index-1)
							&& oz_aux>z_base)
							oz_aux--;

						//Desplazar la nueva caja sobre el eje X
						while(noChocaX(ox_aux,oz_aux,&(*it),colocadas_aux,size_colocadas-index-1)
							&& ox_aux>x_base)
							ox_aux--;

						//Desplazar la nueva caja sobre el eje Z
						while(noChocaZ(ox_aux,oz_aux,&(*it),colocadas_aux,size_colocadas-index-1)
							&& oz_aux>z_base)
							oz_aux--;

						//Comprobar que las coordenadas obtenidas están dentro de las dimensiones
						// de la caja base
						if(oz_aux+(*it).getDepth()<=(*ocupados)[k].colocadas[index].getZ()+(*ocupados)[k].colocadas[index].getDepth()
							&& ox_aux+(*it).getWidth()<=(*ocupados)[k].colocadas[index].getX()+(*ocupados)[k].colocadas[index].getWidth())
						{
							//Se le asigna la caja base
							(*it).setBase(&((*ocupados)[k].colocadas[index]));

							//Llegados aquí, se le asignan las coordenadas a la nueva caja
							(*it).setX(ox_aux); 	
							(*it).setZ(oz_aux);
							(*it).setY((*ocupados)[k].colocadas[size_colocadas-1].getY());				

							//Se actualiza el peso soportado por la caja inferior
							(*it).getBase()->setSuppWeight((*it).getBase()->getSuppWeight() + (*it).getWeight());

							//La insertamos dentro del contenedor
							(*ocupados)[k].insertBox((*it));

							//Una vez colocada la caja, incrementamos los pesos de cada bloque
							//asignaPesoBloque(ocupados, k, (*it));
							//actualizo el peso del contenedor
							sum_w[k]+=(*it).getWeight();

							//elimino de la lista principal la caja que ya meti
							it=aux.erase(it);

							colocar_en_la_base=false;	
						}	
						//Intentar meterla en el 3er nivel sobre la 1º del 2do nivel de las que están
						// sobre la última caja base
						else
						{
							//Buscar la caja del segundo nivel que servirá de base
							for(index=size_colocadas-1; 
								index>=1 && (*ocupados)[k].colocadas[index].getBase()->getY()>0;
								index--);

							//Comprobar que:
							//	#no se supera el límite de altura del contenedor
							//	#la caja base soporta la nueva caja que queremos colocar
							if(index>=1
								&& (*ocupados)[k].colocadas[index].puedeSoportarA((*it),W_LIMIT,HEIGHT))
							{
								//Rellenar un vector de ocupados auxiliar con las cajas que ya están
								// sobre la caja base
								colocadas_aux.resize(size_colocadas-index-1);
								for(int i=0; i<size_colocadas-index-1; i++)
								{
									colocadas_aux[i]=(*ocupados)[k].colocadas[index+i+1];
								}

								//Coordenadas iniciales para desplazar la caja
								z_base=(*ocupados)[k].colocadas[index].getZ();
								oz_aux= z_base + (*ocupados)[k].colocadas[index].getDepth();
								x_base=(*ocupados)[k].colocadas[index].getX();
								ox_aux= x_base + (*ocupados)[k].colocadas[index].getWidth()-(*it).getWidth();

								//Desplazar la nueva caja sobre el eje Z
								while(noChocaZ(ox_aux,oz_aux,&(*it),colocadas_aux,size_colocadas-index-1)
									&& oz_aux>z_base)
									oz_aux--;

								//Desplazar la nueva caja sobre el eje X
								while(noChocaX(ox_aux,oz_aux,&(*it),colocadas_aux,size_colocadas-index-1)
									&& ox_aux>x_base)
									ox_aux--;

								//Desplazar la nueva caja sobre el eje Z
								while(noChocaZ(ox_aux,oz_aux,&(*it),colocadas_aux,size_colocadas-index-1)
									&& oz_aux>z_base)
									oz_aux--;

								//Comprobar que las coordenadas obtenidas están dentro de las dimensiones
								// de la caja base
								if(oz_aux+(*it).getDepth()<=(*ocupados)[k].colocadas[index].getZ()+(*ocupados)[k].colocadas[index].getDepth()
									&& ox_aux+(*it).getWidth()<=(*ocupados)[k].colocadas[index].getX()+(*ocupados)[k].colocadas[index].getWidth())
								{
									//Se le asigna la caja base
									(*it).setBase(&((*ocupados)[k].colocadas[index]));

									//Llegados aquí, se le asignan las coordenadas a la nueva caja
									(*it).setX(ox_aux); 	
									(*it).setZ(oz_aux);
									(*it).setY((*it).getBase()->getY()+(*it).getBase()->getHeight());				

									//Se actualiza el peso soportado por la caja inferior
									(*it).getBase()->setSuppWeight((*it).getBase()->getSuppWeight() + (*it).getWeight());

									//La insertamos dentro del contenedor
									(*ocupados)[k].insertBox((*it));

									//Una vez colocada la caja, incrementamos los pesos de cada bloque
									//asignaPesoBloque(ocupados, k, (*it));
									//actualizo el peso del contenedor
									sum_w[k]+=(*it).getWeight();

									//elimino de la lista principal la caja que ya meti
									it=aux.erase(it);

									colocar_en_la_base=false;	
								}
							}
						}	//else_3er_nivel

					}
				}
				
			}	//else_if_size_colocadas

			if(cajas_fuera)
				break;

			if(colocar_en_la_base)
			{
				//La caja empieza adelante y a la derecha en el contenedor
				(*ocupados)[k].ox=WIDTH-(*it).getWidth();
				(*ocupados)[k].oz=(int)(*ocupados)[k].z_max;

				//La vamos metiendo hasta que choque con otra caja de las colocadas
				while(noChocaZ((*ocupados)[k].ox,(*ocupados)[k].oz,&(*it),(*ocupados)[k].colocadas, (*ocupados)[k].ultima_caja+1)
					&& (*ocupados)[k].oz>0)
					(*ocupados)[k].oz--;

				//La movemos hacia la izq. hasta chocar con otra de las colocadas
				while(noChocaX((*ocupados)[k].ox,(*ocupados)[k].oz,&(*it),(*ocupados)[k].colocadas, (*ocupados)[k].ultima_caja+1)
					&& (*ocupados)[k].ox>0)
					(*ocupados)[k].ox--;

				//Lo intentamos mover de nuevo hacia abajo
				while(noChocaZ((*ocupados)[k].ox,(*ocupados)[k].oz,&(*it),(*ocupados)[k].colocadas, (*ocupados)[k].ultima_caja+1)
					&& (*ocupados)[k].oz>0)
					(*ocupados)[k].oz--;

				(*it).setBase(NULL);

				//Guardamos las posiciones definitivas de la caja
				(*it).setX((*ocupados)[k].ox); 	
				(*it).setZ((*ocupados)[k].oz);
				(*it).setY(0);

				//Comprobar que la caja queda dentro del contenedor
				if((*ocupados)[k].oz+(*it).getDepth()>DEPTH
					|| (*ocupados)[k].ox+(*it).getWidth()>WIDTH)
				{	
					cajas_fuera=true;
					it++;	//Hacerlo aquí para que no de problemas el 'erase' del 'else'
				}
				else
				{
					//La caja entra en el contenedor: actualizo los datos del contenedor y borro la caja de la lista de cajas
					(*ocupados)[k].insertBox((*it));

					//Si al colocar una caja supero el largo que tenia hasta ahora, actualizo z_max del contenedor
					if((*ocupados)[k].z_max < (*it).getZ()+(*it).getDepth())
						(*ocupados)[k].z_max = (*it).getZ()+(*it).getDepth();

					//Una vez colocada la caja, incrementamos los pesos de cada bloque
					//asignaPesoBloque(ocupados, k, (*it));
					//actualizo el peso del contenedor
					sum_w[k]+=(*it).getWeight();

					//elimino de la lista principal la caja que ya meti
					it=aux.erase(it);
				}
			}		
		}

		if(cajas_fuera)
		{	//Hay cajas q se salen del contenedor, creo uno nuevo		
			i_ocupados++;
			sum_w.push_back(0.0);
			cajas_fuera=false;
		}
	
	}

	sol.list_A.clear();
	
	//OJO, NUMBLOQUES==2
	double diff_z = 0.0;
	double diff_percent_z=0.0;
	double diff_x = 0.0;
	double diff_percent_x=0.0;
	double fitness_k = 0.0;
	
	double fitness_container=0.0;
	double sum_vol = 0.0;
	
	//Para cada contenedor
	int ocupados_size=i_ocupados+1;
	for(int i=0; i<ocupados_size; i++)
	{	
				//Calculo la media de las diferencia de peso entre los bloques a lo largo y ancho
		diff_z = ABSOLUTE((*ocupados)[i].bloques_z[0].weight - (*ocupados)[i].bloques_z[1].weight);
		diff_x = ABSOLUTE((*ocupados)[i].bloques_x[0].weight - (*ocupados)[i].bloques_x[1].weight);

		//Calculo el porcentaje de peso que representa la diferencia sobre 1, en lugar de 100
		diff_percent_z = diff_z/sum_w[i];
		diff_percent_x = diff_x/sum_w[i];
		
		//diff_percent=0 es ajuste perfecto
		if(diff_percent_z>W_WEIGHT || diff_percent_x>W_WEIGHT)
		{
			fitness_k = 0;
		}
		else{
			fitness_k = 1 - (diff_percent_z+diff_percent_x)/2.0;
		}
		
		fitness_container += fitness_k/ocupados_size;

		//Acumular los volúmenes de ocupación (en tanto por 100)
		sum_vol += ((*ocupados)[i].getOcupacion())/(double)ocupados_size;

		//Guardo la solucion
		for(int j=0; j<(*ocupados)[i].ultima_caja+1; j++){
			sol.list_A.push_back((*ocupados)[i].colocadas[j]);
		}
	}

	sol.fitness_value = (3*fitness_container + 7*(sum_vol/100.0))/10.0;
	if(sol.fitness_value<0)
		sol.fitness_value = 0;

	delete ocupados;*/
}



/*
*	Realiza el cruce de los individuos de la lista (Cruce simple)
*	Selecciona dos individuos al azar, selecciona una posicion dentro de cada individuo al azar, seleccionando así 2 cajas
*	intercambia las cajas de posicion entre ambos individuos. 
*/
void crossoverOnePoint(pair<Solucion*,Solucion*> &parents, pair<Solucion,Solucion> &children)
{/*	
	list<Solucion> solucion;
	//seleccion.clear();

	list<Solucion>::iterator it1;
	list<Solucion>::iterator it2;
	int pos_aleat,	//selecciona la posicion aleatoria de cada individuo
		aleatorio1,//seleccionan los individuos
		aleatorio2;
	int i=0;
	

	while(seleccion.size()>1){

		it1=seleccion.begin();
		it2=seleccion.begin();

	//Seleccionar 2 individuos al azar
		aleatorio1=rand()%(seleccion.size());
		do
		{
			aleatorio2=rand()%(seleccion.size());
		}while(aleatorio2==aleatorio1);

		advance(it1, aleatorio1);
		advance(it2, aleatorio2);

		(*it1).cruces++;
		(*it2).cruces++;

		//escojo la posicion en la que voy a buscar las cajas a intercambiar
		pos_aleat=rand()%((*it1).list_A.size());
		
		Box b1 = (*it1).list_A[pos_aleat];
		Box b2 = (*it2).list_A[pos_aleat];
		
		//buscar caja b2, en it1
		for(i=0; i<(*it1).list_A.size(); i++)
		{
			if(b2 == (*it1).list_A[i])
				break;
		}

		//en (*it1).list_A[i] tengo la caja b2 meto ahi la caja b1
		(*it1).list_A[i] = b1;
		//en la posicion aleatoria, meto la b2 y asi quedan intercambiadas
		(*it1).list_A[pos_aleat] = b2;

		
		//buscar caja b1 en it2
		for(i=0; i<(*it2).list_A.size(); i++)
		{
			if(b1 == (*it2).list_A[i])
				break;
		}
		//intercambiar caja b1 en it2 por caja b2 en it2
		(*it2).list_A[i] = b2;
		(*it2).list_A[pos_aleat] = b1;

		fitness(*it1);
		fitness(*it2);

		(*it1).cruces=0;
		(*it2).cruces=0;

		solucion.push_back(*it1);
		solucion.push_back(*it2);	

		it1=seleccion.erase(it1);
		it2=seleccion.erase(it2);
	}

	//Si sólo queda 1 individuo, lo añadimos a la seleccion
	if(seleccion.size() == 1){
		Solucion ultimo = seleccion.back();
		ultimo.cruces++;
		solucion.push_back(ultimo);
	}


	seleccion = solucion;
	*/
}


/*
/*bool Container::allocateBox_solo_base(Box &b)
{
	//Comprobación preliminar: peso y altura
	if(this->weight + b.getWeight() > this->weight_lim
		|| b.getHeight() > height)
		return false;

	list<Box>::reverse_iterator it_col;
	list<Box>::iterator it_aux,
			    it_col_base;
	int i,
		cont,
		size_base,
		z_base, x_base, y_base;

	//############	COLOCACIÓN SOBRE LA BASE DEL CONTENEDOR	  ############
	//Si no se pudo colocar sobre otra, intentarlo en la base tras la última
	//Seleccionar una esquina para la caja
/*	size_base = cajasBase.size();

    //La caja empieza adelante y a la derecha en el contenedor
    this->ox=this->width-b.getWidth();
    this->oz=(int)this->z_max;
    this->oy=0;

    //La vamos metiendo hasta que choque con otra caja de las colocadas
    while(noChocaZ_2D(this->ox,this->oz,&b,this->cajasBase, size_base)
            && this->oz>0)
            --(this->oz);

    //La movemos hacia la izq. hasta chocar con otra de las colocadas
    while(noChocaX_2D(this->ox,this->oz,&b,this->cajasBase, size_base)
            && this->ox>0)
            --(this->ox);

    //Lo intentamos mover de nuevo hacia el origen tanto en Z como en X
    while(noChocaZ_2D(this->ox,this->oz,&b,this->cajasBase, size_base)
            && this->oz>0)
            --(this->oz);

    while(noChocaX_2D(this->ox,this->oz,&b,this->cajasBase, size_base)
            && this->ox>0)
            --(this->ox);

    //Comprobar si la caja queda contenida dentro del contenedor
    if( this->oz+b.getDepth() > depth
            || this->ox+b.getWidth() > width)
            return false;

    //La caja cabe en la base del contenedor
    b.setBase(NULL);

    //Guardamos las posiciones definitivas de la caja
    b.setX(this->ox);      
    b.setZ(this->oz);
    b.setY(this->oy);

    //La caja entra en el contenedor: actualizo los datos del contenedor
    this->pushBackBox(b);

    return true;
}
*/




/*bool Container::allocateBox_2_niveles_caja_anterior(Box &b)
{
	//Comprobación preliminar: peso y altura
	if( this->weight + b.getWeight() > this->weight_lim
		|| b.getHeight() > height)
		return false;

	list<Box>::reverse_iterator it_col;
	list<Box>::iterator it_aux,
			    it_col_base;
	int i,
		cont,
		size_base,
		z_base, x_base, y_base;

	bool salir;

	list<Box> colocadas_aux;

	//############	COLOCACIÓN SOBRE OTRAS CAJAS	  ############
/*	//Colocar la caja sobre alguna de las ya contenidas en el contenedor
	cont=0;
	salir=false;
	it_col=colocadas.rbegin();

		if(it_col!=colocadas.rend() &&
		it_col->getBase()==NULL &&
		it_col->puedeSoportarA(b,W_LIMIT))
		{
			
			//Recorro todas las cajas colocadas	
			int num_encima=0;
			colocadas_aux.clear();
			for(it_aux=colocadas.begin(); it_aux!=colocadas.end(); ++it_aux)
			{	
				//Si hay alguna que tenga por base la misma que la caja i, se inserta en el vector
				if(it_aux->getBase() == &(*it_col))
				{
					//Hay que comprobar si la que se inserta es igual de grande que la base, 
					//lo cual indica que ya no es posible colocar nada más encima de esa base y hay que salir de esa iteración 
					if(it_aux->getWidth()==it_col->getWidth()&&it_aux->getDepth()==it_col->getDepth())
					{
						salir = true;
						break;
					}
					else
					{
						colocadas_aux.push_back(*it_aux);
						++num_encima;
					}
				}
			}

			//Si no hay ninguna caja más directamente se coloca en la esquina con menor x y z de la base
			if(num_encima==0)
			{
				//Las esquinas coincidirán con la caja base 
				this->oz = it_col->getZ();
				this->ox = it_col->getX();
				//La coordenada Y sumará a la base la altura
				this->oy = it_col->getY() + it_col->getHeight();

			}
			else
			{
				//Coordenadas iniciales para desplazar la caja
				z_base=it_col->getZ();
				this->oz= z_base + it_col->getDepth();
				y_base =it_col->getY();
				this->oy = y_base + it_col->getHeight();
				x_base=it_col->getX();
				this->ox= x_base + it_col->getWidth()-b.getWidth();

				//La vamos metiendo hasta que choque con otra caja de las colocadas
				while(noChocaZ(this->ox,this->oy,this->oz,&b,colocadas_aux, num_encima)
					&& this->oz>z_base)
					--(this->oz);

				//La movemos hacia la izq. hasta chocar con otra de las colocadas
				while(noChocaX(this->ox,this->oy,this->oz,&b,colocadas_aux, num_encima)
					&& this->ox>x_base)
					--(this->ox);

				//Lo intentamos mover de nuevo hacia el origen tanto en Z como en X
				while(noChocaZ(this->ox,this->oy,this->oz,&b,colocadas_aux, num_encima)
					&& this->oz>z_base)
					--(this->oz);

				while(noChocaX(this->ox,this->oy,this->oz,&b,colocadas_aux, num_encima)
					&& this->ox>x_base)
					--(this->ox);
			}

			//Comprobar si la caja queda contenida dentro de la caja base
			if( this->oz+b.getDepth() > it_col->getZ()+it_col->getDepth()
				|| this->ox+b.getWidth() > it_col->getX()+it_col->getWidth())
			{}
			else{
				//La caja cabe en la base del contenedor
				b.setBase(&(*it_col));
				it_col->setEsBase(true);

				//Se actualiza el peso soportado por la caja inferior
				it_col->addWeight(b.getWeight());

				//Guardamos las posiciones definitivas de la caja
				b.setX(this->ox); 	
				b.setZ(this->oz);
				b.setY(this->oy);

				//La caja entra sobre la otra: actualizo los datos del contenedor 
				it_col_base=it_col.base();
				this->insertBox(b,it_col_base);

				return true;
			}
		}

	//############	COLOCACIÓN SOBRE LA BASE DEL CONTENEDOR	  ############
/*	//Si no se pudo colocar sobre otra, intentarlo en la base tras la última
	if(i>ultima_caja)
	{
		size_base = cajasBase.size();

		//La caja empieza adelante y a la derecha en el contenedor
		this->ox=this->width-b.getWidth();
		this->oz=(int)this->z_max;
		this->oy=0;

		//La vamos metiendo hasta que choque con otra caja de las colocadas
		while(noChocaZ_2D(this->ox,this->oz,&b,this->cajasBase, size_base)
			&& this->oz>0)
			--(this->oz);

		//La movemos hacia la izq. hasta chocar con otra de las colocadas
		while(noChocaX_2D(this->ox,this->oz,&b,this->cajasBase, size_base)
			&& this->ox>0)
			--(this->ox);

		//Lo intentamos mover de nuevo hacia el origen tanto en Z como en X
		while(noChocaZ_2D(this->ox,this->oz,&b,this->cajasBase, size_base)
			&& this->oz>0)
			--(this->oz);

		while(noChocaX_2D(this->ox,this->oz,&b,this->cajasBase, size_base)
			&& this->ox>0)
			--(this->ox);

		//Comprobar si la caja queda contenida dentro del contenedor
		if( this->oz+b.getDepth() > depth
			|| this->ox+b.getWidth() > width)
			return false;

		//La caja cabe en la base del contenedor
		b.setBase(NULL);

		//Guardamos las posiciones definitivas de la caja
		b.setX(this->ox); 	
		b.setZ(this->oz);
		b.setY(this->oy);

		//La caja entra en el contenedor: actualizo los datos del contenedor 
		this->pushBackBox(b);

		return true;
	}

	return false;
}
*/

/*bool Container::allocateBox_2_niveles_cualquier_caja(Box &b)
{
	//Comprobación preliminar: peso y altura
	if( this->weight + b.getWeight() > this->weight_lim
		|| b.getHeight() > height)
		return false;

	list<Box>::reverse_iterator it_col;
	list<Box>::iterator it_aux,
			    it_col_base;
	int i,
		cont,
		size_base,
		z_base, x_base, y_base;

	bool salir;

	list<Box> colocadas_aux;

	//############	COLOCACIÓN SOBRE OTRAS CAJAS	  ############
	//Colocar la caja sobre alguna de las ya contenidas en el contenedor
	cont=0;
	salir=false;
	it_col=colocadas.rbegin();
	for(i=0; i<=this->ultima_caja; ++i,++it_col)
	{
		cont++;

		if(it_col->getBase()==NULL &&
			it_col->puedeSoportarA(b,W_LIMIT,height))
		{
			
			//Recorro todas las cajas colocadas	
			int num_encima=0;
			colocadas_aux.clear();
			for(it_aux=colocadas.begin(); it_aux!=colocadas.end(); ++it_aux)
			{	
				//Si hay alguna que tenga por base la misma que la caja i, se inserta en el vector
				if(it_aux->getBase() == &(*it_col))
				{
					//Hay que comprobar si la que se inserta es igual de grande que la base, 
					//lo cual indica que ya no es posible colocar nada más encima de esa base y hay que salir de esa iteración 
					if(it_aux->getWidth()==it_col->getWidth()&&it_aux->getDepth()==it_col->getDepth())
					{
						salir = true;
						break;
					}
					else
					{
						colocadas_aux.push_back(*it_aux);
						++num_encima;
					}
				}
			}

			if(salir)
			{
				salir = false;			
				continue;
			}

			//Si no hay ninguna caja más directamente se coloca en la esquina con menor x y z de la base
			if(num_encima==0)
			{
				//Las esquinas coincidirán con la caja base 
				this->oz = it_col->getZ();
				this->ox = it_col->getX();
				//La coordenada Y sumará a la base la altura
				this->oy = it_col->getY() + it_col->getHeight();

			}
			else
			{
				//Coordenadas iniciales para desplazar la caja
				z_base=it_col->getZ();
				this->oz= z_base + it_col->getDepth();
				y_base =it_col->getY();
				this->oy = y_base + it_col->getHeight();
				x_base=it_col->getX();
				this->ox= x_base + it_col->getWidth()-b.getWidth();

				//La vamos metiendo hasta que choque con otra caja de las colocadas
				while(noChocaZ(this->ox,this->oy,this->oz,&b,colocadas_aux, num_encima)
					&& this->oz>z_base)
					--(this->oz);

				//La movemos hacia la izq. hasta chocar con otra de las colocadas
				while(noChocaX(this->ox,this->oy,this->oz,&b,colocadas_aux, num_encima)
					&& this->ox>x_base)
					--(this->ox);

				//Lo intentamos mover de nuevo hacia el origen tanto en Z como en X
				while(noChocaZ(this->ox,this->oy,this->oz,&b,colocadas_aux, num_encima)
					&& this->oz>z_base)
					--(this->oz);

				while(noChocaX(this->ox,this->oy,this->oz,&b,colocadas_aux, num_encima)
					&& this->ox>x_base)
					--(this->ox);
			}

			//Comprobar si la caja queda contenida dentro de la caja base
			if( this->oz+b.getDepth() > it_col->getZ()+it_col->getDepth()
				|| this->ox+b.getWidth() > it_col->getX()+it_col->getWidth())
				continue;

			//La caja cabe en la base del contenedor
			b.setBase(&(*it_col));
			it_col->setEsBase(true);

			//Se actualiza el peso soportado por la caja inferior
			it_col->addWeight(b.getWeight());

			//Guardamos las posiciones definitivas de la caja
			b.setX(this->ox); 	
			b.setZ(this->oz);
			b.setY(this->oy);

			//La caja entra sobre la otra: actualizo los datos del contenedor 
			it_col_base=it_col.base();
			this->insertBox(b,it_col_base);

			return true;
		}
	}

	//############	COLOCACIÓN SOBRE LA BASE DEL CONTENEDOR	  ############
	//Si no se pudo colocar sobre otra, intentarlo en la base tras la última
	if(i>ultima_caja)
	{
		size_base = cajasBase.size();

		//La caja empieza adelante y a la derecha en el contenedor
		this->ox=this->width-b.getWidth();
		this->oz=(int)this->z_max;
		this->oy=0;

		//La vamos metiendo hasta que choque con otra caja de las colocadas
		while(noChocaZ_2D(this->ox,this->oz,&b,this->cajasBase, size_base)
			&& this->oz>0)
			--(this->oz);

		//La movemos hacia la izq. hasta chocar con otra de las colocadas
		while(noChocaX_2D(this->ox,this->oz,&b,this->cajasBase, size_base)
			&& this->ox>0)
			--(this->ox);

		//Lo intentamos mover de nuevo hacia el origen tanto en Z como en X
		while(noChocaZ_2D(this->ox,this->oz,&b,this->cajasBase, size_base)
			&& this->oz>0)
			--(this->oz);

		while(noChocaX_2D(this->ox,this->oz,&b,this->cajasBase, size_base)
			&& this->ox>0)
			--(this->ox);

		//Comprobar si la caja queda contenida dentro del contenedor
		if( this->oz+b.getDepth() > depth
			|| this->ox+b.getWidth() > width)
			return false;

		//La caja cabe en la base del contenedor
		b.setBase(NULL);

		//Guardamos las posiciones definitivas de la caja
		b.setX(this->ox); 	
		b.setZ(this->oz);
		b.setY(this->oy);

		//La caja entra en el contenedor: actualizo los datos del contenedor 
		this->pushBackBox(b);

		return true;
	}

	return false;
}



bool Container::allocateBox_N_niveles_caja_anterior(Box &b)
{
	//Comprobación preliminar: peso y altura
	if( this->weight + b.getWeight() > this->weight_lim
		|| b.getHeight() > height)
		return false;

	list<Box>::reverse_iterator it_col;
	list<Box>::iterator it_aux,
			    it_col_base;
	int i,
		cont,
		size_base,
		z_base, x_base, y_base;

	bool salir;

	list<Box> colocadas_aux;

	//############	COLOCACIÓN SOBRE OTRAS CAJAS	  ############
	//Colocar la caja sobre alguna de las ya contenidas en el contenedor
	cont=0;
	salir=false;
	it_col=colocadas.rbegin();
	//for(i=0; i<=this->ultima_caja; ++i,++it_col)
	//{

		if(it_col->puedeSoportarA(b,W_LIMIT))
		{			
			//Recorro todas las cajas colocadas	
			int num_encima=0;
			colocadas_aux.clear();
			for(it_aux=colocadas.begin(); it_aux!=colocadas.end(); ++it_aux)
			{	
				//Si hay alguna que tenga por base la misma que la caja i, se inserta en el vector
				if(it_aux->getBase() == &(*it_col))
				{
					//Hay que comprobar si la que se inserta es igual de grande que la base, 
					//lo cual indica que ya no es posible colocar nada más encima de esa base y hay que salir de esa iteración 
					if(it_aux->getWidth()==it_col->getWidth()&&it_aux->getDepth()==it_col->getDepth())
					{
						salir = true;
						break;
					}
					else
					{
						colocadas_aux.push_back(*it_aux);
						++num_encima;
					}
				}
			}

			if(salir)
			{
				salir = false;			
				//continue;
			
			}

			//Si no hay ninguna caja más directamente se coloca en la esquina con menor x y z de la base
			if(num_encima==0)
			{
				//Las esquinas coincidirán con la caja base 
				this->oz = it_col->getZ();
				this->ox = it_col->getX();
				//La coordenada Y sumará a la base la altura
				this->oy = it_col->getY() + it_col->getHeight();

			}
			//Coordenadas iniciales para desplazar la caja
			z_base=it_col->getZ();
			this->oz= z_base + it_col->getDepth();
			y_base =it_col->getY();
			this->oy = y_base + it_col->getHeight();
			x_base=it_col->getX();
			this->ox= x_base + it_col->getWidth()-b.getWidth();

			//La vamos metiendo hasta que choque con otra caja de las colocadas
			while(noChocaZ(this->ox,this->oy,this->oz,&b,colocadas_aux, num_encima)
				&& this->oz>z_base)
				--(this->oz);

			//La movemos hacia la izq. hasta chocar con otra de las colocadas
			while(noChocaX(this->ox,this->oy,this->oz,&b,colocadas_aux, num_encima)
				&& this->ox>x_base)
				--(this->ox);

			//Lo intentamos mover de nuevo hacia el origen tanto en Z como en X
			while(noChocaZ(this->ox,this->oy,this->oz,&b,colocadas_aux, num_encima)
				&& this->oz>z_base)
				--(this->oz);

			while(noChocaX(this->ox,this->oy,this->oz,&b,colocadas_aux, num_encima)
				&& this->ox>x_base)
				--(this->ox);

			//Comprobar si la caja queda contenida dentro de la caja base
			if( this->oz+b.getDepth() > it_col->getZ()+it_col->getDepth()
				|| this->ox+b.getWidth() > it_col->getX()+it_col->getWidth())
			{

			}

			else{
			//La caja cabe en la base del contenedor
			b.setBase(&(*it_col));
			it_col->setEsBase(true);

			//Se actualiza el peso soportado por la caja inferior
			it_col->addWeight(b.getWeight());

			//Guardamos las posiciones definitivas de la caja
			b.setX(this->ox); 	
			b.setZ(this->oz);
			b.setY(this->oy);

			//La caja entra sobre la otra: actualizo los datos del contenedor 
			it_col_base=it_col.base();
			this->insertBox(b,it_col_base);

			return true;
			}
		}
	//}

	//############	COLOCACIÓN SOBRE LA BASE DEL CONTENEDOR	  ############
	//Si no se pudo colocar sobre otra, intentarlo en la base tras la última
	if(i>ultima_caja)
	{
		size_base = cajasBase.size();

		//La caja empieza adelante y a la derecha en el contenedor
		this->ox=this->width-b.getWidth();
		this->oz=(int)this->z_max;
		this->oy=0;

		//La vamos metiendo hasta que choque con otra caja de las colocadas
		while(noChocaZ_2D(this->ox,this->oz,&b,this->cajasBase, size_base)
			&& this->oz>0)
			--(this->oz);

		//La movemos hacia la izq. hasta chocar con otra de las colocadas
		while(noChocaX_2D(this->ox,this->oz,&b,this->cajasBase, size_base)
			&& this->ox>0)
			--(this->ox);

		//Lo intentamos mover de nuevo hacia el origen tanto en Z como en X
		while(noChocaZ_2D(this->ox,this->oz,&b,this->cajasBase, size_base)
			&& this->oz>0)
			--(this->oz);

		while(noChocaX_2D(this->ox,this->oz,&b,this->cajasBase, size_base)
			&& this->ox>0)
			--(this->ox);

		//Comprobar si la caja queda contenida dentro del contenedor
		if( this->oz+b.getDepth() > depth
			|| this->ox+b.getWidth() > width)
			return false;

		//La caja cabe en la base del contenedor
		b.setBase(NULL);

		//Guardamos las posiciones definitivas de la caja
		b.setX(this->ox); 	
		b.setZ(this->oz);
		b.setY(this->oy);

		//La caja entra en el contenedor: actualizo los datos del contenedor 
		this->pushBackBox(b);

		return true;
	}

	return false;
}
*/

